package com.eningqu.aipen.ui.home.book;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.PixelCopy;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.alibaba.fastjson.JSONObject;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.ScreenUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.bumptech.glide.Glide;
import com.eningqu.aipen.demo.PenCtrlSdkManager;
import com.eningqu.aipen.demo.R;
import com.eningqu.aipen.demo.common.Const;
import com.eningqu.aipen.demo.common.HttpUtils;
import com.eningqu.aipen.demo.databinding.ActivityWriteBinding;
import com.eningqu.aipen.demo.listener.TouchListener;
import com.eningqu.aipen.demo.view.CanvasDrawView;
import com.eningqu.aipen.demo.view.CanvasFrame;
import com.eningqu.aipen.logic.model.chat.ChatBodyBean;
import com.eningqu.aipen.logic.network.Apis;
import com.eningqu.aipen.logic.network.ChatRetrofitUtils;
import com.eningqu.aipen.logic.network.SchedulerTransformer;
import com.eningqu.aipen.sdk.bean.DotType;
import com.eningqu.aipen.sdk.bean.NQDot;
import com.eningqu.aipen.sdk.comm.ConnectState;
import com.eningqu.aipen.sdk.comm.utils.BytesConvert;
import com.eningqu.aipen.sdk.listener.PenDotListener;
import com.eningqu.aipen.sdk.listener.PenOfflineDataListener;
import com.eningqu.aipen.ui.adapter.MsgAdapter;
import com.eningqu.aipen.ui.base.BaseActivity;
import com.eningqu.aipen.ui.view.LoadingView;
import com.eningqu.aipen.utils.Constants;
import com.eningqu.aipen.utils.GlobalConfig;
import com.eningqu.aipen.utils.PopTipUtils;
import com.google.common.collect.BiMap;
import com.kongzue.dialogx.dialogs.FullScreenDialog;
import com.kongzue.dialogx.dialogs.PopTip;
import com.kongzue.dialogx.interfaces.OnBindView;
import com.luck.picture.lib.basic.PictureSelector;
import com.luck.picture.lib.config.PictureConfig;
import com.luck.picture.lib.config.PictureMimeType;
import com.luck.picture.lib.config.SelectMimeType;
import com.luck.picture.lib.engine.CompressFileEngine;
import com.luck.picture.lib.entity.LocalMedia;
import com.luck.picture.lib.interfaces.OnKeyValueResultCallbackListener;
import com.luck.picture.lib.utils.DateUtils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

import okhttp3.MediaType;
import okhttp3.RequestBody;
import top.zibin.luban.Luban;
import top.zibin.luban.OnNewCompressListener;
import top.zibin.luban.OnRenameListener;

/**
 * Package:com.eningqu.aipen.ui.home.book
 * Author:starr
 * Time:2023/9/18  10:39
 * Description: 实时书写的界面
 */

public class WriteActivity extends BaseActivity<ActivityWriteBinding> {

    private SendThread sendThread;//实时转换字迹的线程
    private static Integer blId;//病历ID
    private static Integer blModel;//病历模板
    private static Integer ghId;//挂号id
    private static Integer hzId;//患者id
    private static Bitmap modelBackground = null;//病历背景模板
    private CanvasFrame mCurCanvasFrame;//自定义画布
    private CanvasDrawView mCurDrawView;
    private HashMap<String, Bitmap> bitmapMap = new HashMap<String, Bitmap>();//病历点位截图的列表

    //图片选择适配器
    private ArrayList<LocalMedia> mData = new ArrayList<>();

    private ArrayList<LocalMedia> mFaceData = new ArrayList<>();
    private ArrayList<LocalMedia> mTongueData = new ArrayList<>();
    private int typeImg = 0;//0是面诊，1是舌诊


    private boolean aiFlag = false;
    private boolean newPageFlag = false;
    private boolean picFlag = false;
    private boolean saveFlag = false;
    private boolean redFlag = false;
    private boolean blackFlag = false;

    private boolean aiEastFlag = false;
    private boolean faceEastFlag = false;
    private boolean tongueEastFlag = false;
    private boolean saveEastFlag = false;
    private MsgAdapter adapter;


    //消息实体类
    List<ChatBodyBean.MessagesDTO> messagesDTOList = new ArrayList<>();

    private StringBuilder words;
    private Bitmap bitmap = null;

    /**
     * 笔画粗细
     */
    final private int THIN = 2;
    final private int NORMAL = 4;
    final private int THICK = 6;

    /**
     * 笔画颜色
     */

    final private int BLACK = 1;
    final private int RED = 2;
    final private int GREEN = 3;
    final private int BLUE = 4;

    private final StringBuilder mDotsSb = new StringBuilder();
    private final float pageWHRatio = (float) 148 / 211;//纸张宽高比，默认a4

    private String mMac;//网卡mac地址
    SharedPreferences pref = null;

    private long mOfflineDataDots = 0;//离线数据点数量


    @SuppressLint("HandlerLeak")
    private final Handler mHandler = new Handler() {
        @SuppressLint({"HandlerLeak", "SetTextI18n"})
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 1) {
            } else if (msg.what == 2) {
            } else if (msg.what == 3) {
                mBinding.tvPage.setText("Page:" + msg.arg1);
            }
        }
    };

    public static void startAction(Context context, Bundle bundle) {
        Intent intent = new Intent(context, WriteActivity.class);
        blId = bundle.getInt("blId");
        ghId = bundle.getInt("ghId");
        hzId = bundle.getInt("hzId");
        blModel = bundle.getInt("blModel");
        context.startActivity(intent);
    }

    @Override
    protected int getLayoutId() {
        return R.layout.activity_write;
    }

    @Override
    protected void initView() {
        getWindow().setFormat(PixelFormat.TRANSLUCENT);
        //固定竖屏
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
        //屏幕常亮
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        pref = PreferenceManager.getDefaultSharedPreferences(getContext());
        mCurCanvasFrame = new CanvasFrame(getContext());
        mCurDrawView = mCurCanvasFrame.bDrawl;
        if (blModel == 0) {
            //西医
            modelBackground = BitmapFactory.decodeResource(getResources(), R.drawable.bg_west);
        } else {
            //中医
            modelBackground = BitmapFactory.decodeResource(getResources(), R.drawable.bg_east);
        }
        mCurDrawView.setBackImage(modelBackground);
        PenCtrlSdkManager.getInstance().setPageSizeForA4();

        //初始化画板
        initDrawBroad(mBinding.flDrawBoard, mCurCanvasFrame);
        //获取网卡mac，也可以用其他唯一值来替代
        mMac = BytesConvert.bcdToString(HttpUtils.getMacFromHardware());
        if (sendThread == null) {
            sendThread = new SendThread(mMac, mCurDrawView, mHandler);
        }
        sendThread.setDaemon(true);
        sendThread.start();
        //设置笔的监听
        setListener();
    }

    /**
     * 初始化画板
     */
    private void initDrawBroad(@NonNull final FrameLayout frameLayout, @NonNull final CanvasFrame canvasFrame) {

        if (canvasFrame.initDrawBroad) {
            LogUtils.d("已装载画板");
            return;
        }

        LogUtils.d("装载画板");

        frameLayout.post(new Runnable() {
            public void run() {


                if (!canvasFrame.initDrawBroad) {
                    int width = ScreenUtils.getScreenWidth();
                    int height = (int) ((float) ScreenUtils.getScreenWidth() / pageWHRatio);

                    FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(width, height);
                    layoutParams.width = ScreenUtils.getScreenWidth();

                    canvasFrame.setLayoutParams(layoutParams);

                    final CanvasDrawView drawView = canvasFrame.bDrawl;
                    if (null != drawView) {
                        drawView.setZOrderOnTop(true); // 在最顶层，会遮挡一切view
                        drawView.setZOrderMediaOverlay(true);// 如已绘制SurfaceView则在surfaceView上一层绘制。
                        drawView.setDrawing(true);
                    }
                }


                canvasFrame.getViewTreeObserver().addOnGlobalLayoutListener(
                        new ViewTreeObserver.OnGlobalLayoutListener() {
                            @SuppressLint("ClickableViewAccessibility")
                            @Override
                            public void onGlobalLayout() {
                                LogUtils.d("onGlobalLayout 设置触摸监听");
                                canvasFrame.getViewTreeObserver().removeOnGlobalLayoutListener(this);

                                frameLayout.setOnTouchListener(new TouchListener(canvasFrame, frameLayout.getWidth(),
                                        frameLayout.getHeight(), canvasFrame.getMeasuredWidth(), canvasFrame.getMeasuredHeight()));

                                LogUtils.i("frameLayout.getWidth()=" + frameLayout.getWidth() + "\n" +
                                        "frameLayout.getHeight()=" + frameLayout.getHeight() + "\n" +
                                        "canvasFrame.getMeasuredWidth()=" + canvasFrame.getMeasuredWidth() + "\n" +
                                        "canvasFrame.getMeasuredHeight()=" + canvasFrame.getMeasuredHeight());


                                //获取纸张的实际宽高
                                @SuppressLint("UseCompatLoadingForDrawables") Drawable page = getDrawable(R.drawable.bg_west);
                                page.getMinimumWidth();
                                page.getMinimumHeight();
                                LogUtils.i("width=" + page.getMinimumWidth() + "\n" +
                                        "height=" + page.getMinimumHeight());


                                //设置笔默认的颜色和大小
                                setDefaultPenSizeAndColour();

                                canvasFrame.initDrawBroad = true;
                            }
                        });

                frameLayout.removeAllViews();
                frameLayout.addView(canvasFrame);
            }
        });
    }

    /**
     * 设置笔默认的颜色和大小
     */
    private void setDefaultPenSizeAndColour() {
        LogUtils.d("设置笔默认的颜色和大小");
        //获取缓存的笔画粗细,默认THIN
        int thickness = pref.getInt(Const.Pref.KEY_THICKNESS, THIN);
        Message message = Message.obtain();
        message.what = 1;
        switch (thickness) {
            case THIN:
                message.arg1 = 1;
                break;
            case NORMAL:
                message.arg1 = 2;
                break;
            case THICK:
                message.arg1 = 3;
                break;
        }

        //获取缓存的笔画颜色,默认BLACK
        int color = pref.getInt(Const.Pref.KEY_COLOR, BLACK);
        switch (color) {
            case BLACK:
                message.arg2 = 1;
                break;
            case RED:
                message.arg2 = 2;
                break;
            case GREEN:
                message.arg2 = 3;
                break;
            case BLUE:
                message.arg2 = 4;
                break;
        }
        mHandler.sendMessage(message);
    }

    @Override
    protected void initData() {
        mBinding.includePenSize.setClick(new WriteClick());
        mBinding.includePenColor.setClick(new WriteClick());
        mBinding.setClick(new WriteClick());
    }

    @Override
    protected void async() {

    }

    private void setListener() {
        //设置实时书写点接收监听
        PenCtrlSdkManager.getInstance().setDotListener(penDotListener);
        //监听离线同步数据
        PenCtrlSdkManager.getInstance().setPenOfflineDataListener(offlineDataListener);
    }

    /**
     * 存放点的信息
     */
    private static Queue<NQDot> nqDotQueue = new ConcurrentLinkedQueue<>();//保存当前操作的页面的点的信息
    private static final LinkedHashMap<Integer, Queue<NQDot>> nqMap = new LinkedHashMap<>();//存放多个页面的笔迹，键为页面

    /**
     * 静态内部类，用于实时书写的线程
     */
    private class SendThread extends Thread {
        //共享资源
        private final Object lock = new Object();

        private final String mac;
        private final CanvasDrawView canvasDrawView;
        private int page = -1;
        private final Handler handler;

        public SendThread(String mac, CanvasDrawView canvasDrawView, Handler handler) {
            this.mac = mac;
            this.canvasDrawView = canvasDrawView;
            this.handler = handler;
        }

        void resumeThread() {
            synchronized (lock) {
                lock.notify();
            }
        }

        void onPause() {
            synchronized (lock) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void run() {
            while (true) {
                while (!nqDotQueue.isEmpty()) {
                    NQDot nqDot = nqDotQueue.poll();
                    assert nqDot != null;
                    LogUtils.d("本地SDK返回: type=" + nqDot.type + "， dot.x=" + nqDot.x + " dot.y=" + nqDot.y
                            + ", page=" + nqDot.page + "，bookNum=" + nqDot.bookNum
                            + ", Width=" + nqDot.book_width + ", Height=" + nqDot.book_height);

                    //西医病历
                    if (blModel == 0) {
                        //ai点位
                        if (nqDot.x >= Constants.WestPage.AI_X && nqDot.x <= Constants.WestPage.AI_END_X &&
                                nqDot.y >= Constants.WestPage.AI_Y && nqDot.y <= Constants.WestPage.AI_END_Y
                        ) {
                            if (!aiFlag) {
                                runOnUiThread(WriteActivity.this::clickAiHelp);
                                aiFlag = !aiFlag;
                            }
                            mHandler.postDelayed(() -> aiFlag = !aiFlag, 1000);
                        }

                        //新建病历点位
                        if (nqDot.x >= Constants.WestPage.NEW_PAGE_X && nqDot.x <= Constants.WestPage.NEW_PAGE_END_X &&
                                nqDot.y >= Constants.WestPage.NEW_PAGE_Y && nqDot.y <= Constants.WestPage.NEW_PAGE_END_Y
                        ) {
                            if (!newPageFlag) {
                                canvasDrawView.cleanCanvas();//清空页面相当于新建了一个页面
                                newPageFlag = !newPageFlag;
                                runOnUiThread(() -> com.eningqu.aipen.utils.ToastUtils.showToast(getContext(), "成功创建新病历"));
                            }
                            mHandler.postDelayed(() -> newPageFlag = !newPageFlag, 1000);
                        }

                        //保存病历
                        if (nqDot.x >= Constants.WestPage.SAVE_X && nqDot.x <= Constants.WestPage.SAVE_END_X &&
                                nqDot.y >= Constants.WestPage.SAVE_Y && nqDot.y <= Constants.WestPage.SAVE_END_Y
                        ) {
                            if (!saveFlag) {
                                runOnUiThread(WriteActivity.this::clickWriteCognize);
                                saveFlag = !saveFlag;
                            }
                            mHandler.postDelayed(() -> saveFlag = !saveFlag, 1000);
                        }

                        //拍照记录
                        if (nqDot.x >= Constants.WestPage.PIC_X && nqDot.x <= Constants.WestPage.PIC_END_X &&
                                nqDot.y >= Constants.WestPage.PIC_Y && nqDot.y <= Constants.WestPage.PIC_END_Y
                        ) {
                            if (!picFlag) {
                                runOnUiThread(WriteActivity.this::takePicture);
                                picFlag = !picFlag;
                            }
                            mHandler.postDelayed(() -> picFlag = !picFlag, 1000);
                        }

                        //红色点位
                        if (nqDot.x >= Constants.WestPage.RED_X && nqDot.x <= Constants.WestPage.RED_END_X &&
                                nqDot.y >= Constants.WestPage.RED_Y && nqDot.y <= Constants.WestPage.RED_END_Y
                        ) {
                            if (!redFlag) {
                                runOnUiThread(WriteActivity.this::clickPenColorRed);
                                redFlag = !redFlag;
                            }
                            mHandler.postDelayed(() -> redFlag = !redFlag, 1000);
                        }
                        //黑色点位
                        if (nqDot.x >= Constants.WestPage.BLACK_X && nqDot.x <= Constants.WestPage.BLACK_END_X &&
                                nqDot.y >= Constants.WestPage.BLACK_Y && nqDot.y <= Constants.WestPage.BLACK_END_Y
                        ) {
                            if (!blackFlag) {
                                runOnUiThread(WriteActivity.this::clickPenColorBlack);
                                blackFlag = !blackFlag;
                            }
                            mHandler.postDelayed(() -> blackFlag = !blackFlag, 1000);
                        }
                        //中医病历
                    } else if (blModel == 1) {
                        //ai点位
                        if (nqDot.x >= Constants.EastPage.AI_X && nqDot.x <= Constants.EastPage.AI_END_X &&
                                nqDot.y >= Constants.EastPage.AI_Y && nqDot.y <= Constants.EastPage.AI_END_Y
                        ) {
                            if (!aiEastFlag) {
                                runOnUiThread(WriteActivity.this::clickAiHelp);
                                aiEastFlag = !aiEastFlag;
                            }
                            mHandler.postDelayed(() -> aiEastFlag = !aiEastFlag, 1000);
                        }

                        //面诊拍照记录
                        if (nqDot.x >= Constants.EastPage.FACE_X && nqDot.x <= Constants.EastPage.FACE_END_X &&
                                nqDot.y >= Constants.EastPage.FACE_Y && nqDot.y <= Constants.EastPage.FACE_END_Y
                        ) {
                            if (!faceEastFlag) {
                                runOnUiThread(WriteActivity.this::takePicture);
                                typeImg = 0;
                                faceEastFlag = !faceEastFlag;
                            }
                            mHandler.postDelayed(() -> faceEastFlag = !faceEastFlag, 1000);
                        }

                        //舌诊拍照
                        if (nqDot.x >= Constants.EastPage.TONGUE_X && nqDot.x <= Constants.EastPage.TONGUE_END_X &&
                                nqDot.y >= Constants.EastPage.TONGUE_Y && nqDot.y <= Constants.EastPage.TONGUE_END_Y
                        ) {
                            if (!tongueEastFlag) {
                                runOnUiThread(WriteActivity.this::takePicture);
                                typeImg = 1;
                                tongueEastFlag = !tongueEastFlag;
                            }
                            mHandler.postDelayed(() -> tongueEastFlag = !tongueEastFlag, 1000);
                        }

                        //保存病历
                        if (nqDot.x >= Constants.EastPage.SAVE_X && nqDot.x <= Constants.EastPage.SAVE_END_X &&
                                nqDot.y >= Constants.EastPage.SAVE_Y && nqDot.y <= Constants.EastPage.SAVE_END_Y
                        ) {
                            if (!saveEastFlag) {
                                runOnUiThread(WriteActivity.this::clickWriteCognize);
                                saveEastFlag = !saveEastFlag;
                            }
                            mHandler.postDelayed(() -> saveEastFlag = !saveEastFlag, 1000);
                        }
                    }

                    if (page == -1) {//第一次更新页面信息
                        page = nqDot.page;
                    } else {
                        if (page != nqDot.page) {//点阵笔迹携带的页面信息与界面展示的界面信息不一样
                            Message message = new Message();
                            page = nqDot.page;
                            message.what = 3;
                            message.arg1 = page;
                            handler.sendMessage(message);
                            canvasDrawView.cleanCanvas();//更换页面，清空页面
                            continue;
                        }
                    }
                    canvasDrawView.addDot(mac, nqDot);
                }
                onPause();
            }
        }
    }

    /**
     * 实时书写点监听
     */
    PenDotListener penDotListener = new PenDotListener() {
        @SuppressLint("SetTextI18n")
        @Override
        public void onReceiveDot(final NQDot nqDot) {

            LogUtils.d("本地SDK返回: type=" + nqDot.type + "， dot.x=" + nqDot.x + " dot.y=" + nqDot.y
                    + ", page=" + nqDot.page + "，bookNum=" + nqDot.bookNum
                    + ", Width=" + nqDot.book_width + ", Height=" + nqDot.book_height);

            if (mDotsSb.length() > 4096) {
                //避免数据太多，及时清理
                mDotsSb.delete(0, 1024);
            }

            runOnUiThread(() -> {
                mBinding.tvPage.setText("Page:" + nqDot.page);
                mCurDrawView.addDot(mMac, nqDot);
            });

            if (nqDot.type == DotType.PEN_ACTION_DOWN) {
                //按下笔
                mDotsSb.append("(").append(nqDot.x).append(",").append(nqDot.y).append(")").append("  Down\n");
            } else if (nqDot.type == DotType.PEN_ACTION_MOVE) {
                //移动笔
                mDotsSb.append("(").append(nqDot.x).append(",").append(nqDot.y).append(")").append("  Move\n");
            } else if (nqDot.type == DotType.PEN_ACTION_UP) {
                //抬起笔
                mDotsSb.append("(").append(nqDot.x).append(",").append(nqDot.y).append(")").append("  Up\n");
//                mnPreXvalue = 0;
            }

            nqDotQueue = nqMap.getOrDefault(nqDot.page, new ConcurrentLinkedQueue<>());
            nqDotQueue.add(nqDot);
            nqMap.put(nqDot.page, nqDotQueue);
            LogUtils.d("当前页面：" + nqDot.page + " 当前nqDotQueue：" + nqDotQueue);

            sendThread.resumeThread();
        }

        @Override
        public void onError(int error, String message) {
            ToastUtils.showLong("异常信息: Msg=" + message + "， error=" + error);
        }
    };


    /**
     * 离线数据监听
     */
    PenOfflineDataListener offlineDataListener = new PenOfflineDataListener() {
        @Override
        public void offlineDataSyncStart(long l) {
            ToastUtils.showShort("开始同步离线数据 Len=" + l + " byte");
        }

        @Override
        public void offlineDataSyncStop() {
            mBinding.offlinedata.postDelayed(() -> PenCtrlSdkManager.getInstance().requestDeleteOfflineData(), 2000);
            ToastUtils.showShort("同步完成");
        }

        @Override
        public void offlineDataDidReceivePenData(final NQDot nqDot) {
            runOnUiThread(() -> {
//                        LogUtils.d("离线数据本地SDK返回: type=" + nqDot.type + "， dot.x=" + nqDot.x + " dot.y=" + nqDot.y
//                                + ", page=" + nqDot.page + "，bookNum=" + nqDot.bookNum
//                                + ", Width=" + nqDot.book_width + ", Height=" + nqDot.book_height);
                mCurDrawView.addDot(mMac, nqDot);
                if (nqDot.type == DotType.PEN_ACTION_DOWN) {
                    mBinding.tvPage.setText("Page:" + nqDot.page);
                }
            });
        }

        @Override
        public void offlineDataDel() {
            ToastUtils.showShort("成功删除离线数据");
        }

        @Override
        public void offlineDataLength(long l) {
            ToastUtils.showShort("离线数据数量:" + l);
            mOfflineDataDots = l;
        }

        @Override
        public void onOffLineCurrentDataLength(long l) {

        }

    };


    /**
     * 点击事件
     * 切换笔迹大小
     * 切换笔迹颜色
     */
    @SuppressWarnings("all")
    public class WriteClick {
        public void penSizeSmall(View view) {
            mBinding.includePenSize.ivPenSizeThin.setBackgroundResource(R.drawable.shape_color_bg_white);
            mBinding.includePenSize.ivPenSizeMid.setBackground(null);
            mBinding.includePenSize.ivPenSizeThick.setBackground(null);
            mCurCanvasFrame.bDrawl.setSize(THIN);
            pref.edit().putInt(Const.Pref.KEY_THICKNESS, THIN).commit();
        }

        public void penSizeMid(View view) {
            mBinding.includePenSize.ivPenSizeThin.setBackground(null);
            mBinding.includePenSize.ivPenSizeMid.setBackgroundResource(R.drawable.shape_color_bg_white);
            mBinding.includePenSize.ivPenSizeThick.setBackground(null);
            mCurCanvasFrame.bDrawl.setSize(NORMAL);
            pref.edit().putInt(Const.Pref.KEY_THICKNESS, NORMAL).commit();
        }

        public void penSizeThick(View view) {
            mBinding.includePenSize.ivPenSizeThin.setBackground(null);
            mBinding.includePenSize.ivPenSizeMid.setBackground(null);
            mBinding.includePenSize.ivPenSizeThick.setBackgroundResource(R.drawable.shape_color_bg_white);
            mCurCanvasFrame.bDrawl.setSize(THICK);
            pref.edit().putInt(Const.Pref.KEY_THICKNESS, THICK).commit();
        }

        public void penColorBlack(View view) {
            clickPenColorBlack();
        }

        //red
        public void penColorRed(View view) {
            clickPenColorRed();
        }

        //green
        public void penColorGreen(View view) {
            mBinding.includePenColor.ivPenColorGreen.setBackgroundResource(R.drawable.shape_color_bg_white);
            mBinding.includePenColor.ivPenColorRed.setBackground(null);
            mBinding.includePenColor.ivPenColorBlack.setBackground(null);
            mBinding.includePenColor.ivPenColorBlue.setBackground(null);

            mCurCanvasFrame.bDrawl.setColor(ContextCompat.getColor(getContext(), R.color.color_45D151));
        }

        //blue
        public void penColorBlue(View view) {
            mBinding.includePenColor.ivPenColorBlue.setBackgroundResource(R.drawable.shape_color_bg_white);
            mBinding.includePenColor.ivPenColorRed.setBackground(null);
            mBinding.includePenColor.ivPenColorGreen.setBackground(null);
            mBinding.includePenColor.ivPenColorBlack.setBackground(null);

            mCurCanvasFrame.bDrawl.setColor(ContextCompat.getColor(getContext(), R.color.color_0D7993));
        }

        //离线数据
        public void penOfflineData(View view) {
            //请求离线数据
            PopTip.tip("正在请求离线数据");
            if (PenCtrlSdkManager.getInstance().getConnState() == ConnectState.CONN_STATE_CONNECTED) {
                PenCtrlSdkManager.getInstance().requestOfflineDataWithRange(0, (int) mOfflineDataDots);
            }
        }

        //ai智能手写体识别
        public void penAiCognize(View view) {
            clickWriteCognize();
        }

        //辅助断针
        public void aiHelp(View view) {
            clickAiHelp();
        }


        //测试模拟书写
        public void testWrite(View view) {
            mCurDrawView.setBackImage(BitmapFactory.decodeResource(getResources(), R.drawable.bg_west_test));
        }

        public void acPage(View view) {

            if (bitmap == null) {
                bitmap = screenshot(mCurDrawView);
            }
            float ratioX = ((float) mCurDrawView.getWidth() / (float) Constants.A4_WIDTH);
            float ratioY = ((float) mCurDrawView.getHeight() / (float) Constants.A4_HEIGHT);
            Bitmap main = Bitmap.createBitmap(bitmap,
                    (int) (Constants.WestPage.MAIN_X * ratioX),
                    (int) (Constants.WestPage.MAIN_Y * ratioY),
                    (int) (Constants.WestPage.MAIN_WIDTH * ratioX),
                    (int) (Constants.WestPage.MAIN_HEIGHT * ratioY));

            mBinding.ivBg.setVisibility(View.VISIBLE);
            Glide.with(getContext()).load(main).into(mBinding.ivBg);
        }
    }

    private void clickPenColorBlack() {
        mBinding.includePenColor.ivPenColorBlack.setBackgroundResource(R.drawable.shape_color_bg_white);
        mBinding.includePenColor.ivPenColorRed.setBackground(null);
        mBinding.includePenColor.ivPenColorGreen.setBackground(null);
        mBinding.includePenColor.ivPenColorBlue.setBackground(null);

        mCurCanvasFrame.bDrawl.setColor(ContextCompat.getColor(getContext(), R.color.color_000000));
        pref.edit().putInt(Const.Pref.KEY_COLOR, BLACK).commit();
    }

    private void clickPenColorRed() {
        mBinding.includePenColor.ivPenColorRed.setBackgroundResource(R.drawable.shape_color_bg_white);
        mBinding.includePenColor.ivPenColorBlack.setBackground(null);
        mBinding.includePenColor.ivPenColorGreen.setBackground(null);
        mBinding.includePenColor.ivPenColorBlue.setBackground(null);

        mCurCanvasFrame.bDrawl.setColor(ContextCompat.getColor(getContext(), R.color.color_E60012));
        pref.edit().putInt(Const.Pref.KEY_COLOR, BLACK).commit();
    }

    private void clickWriteCognize() {
        PopTipUtils.warnMsg("正在处理病历，请稍等...");
        //更换界面后延时2秒跳转
        mHandler.postDelayed(() -> {
            float ratioX = ((float) mCurDrawView.getWidth() / (float) Constants.A4_WIDTH);
            float ratioY = ((float) mCurDrawView.getHeight() / (float) Constants.A4_HEIGHT);

            bitmap = screenshot(mCurDrawView);
            try {
                Thread.sleep(500);//主线程暂停0.5s用于缓存bitmap
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            switch (blModel) {
                //西医病历
                case 0: {
                    Bitmap tem = Bitmap.createBitmap(bitmap,
                            (int) (Constants.WestPage.TEM_X * ratioX),
                            (int) (Constants.WestPage.TEM_Y * ratioY),
                            (int) (Constants.WestPage.TEM_WIDTH * ratioX),
                            (int) (Constants.WestPage.TEM_HEIGHT * ratioY));
                    Bitmap breath = Bitmap.createBitmap(bitmap,
                            (int) (Constants.WestPage.BREATH_X * ratioX),
                            (int) (Constants.WestPage.BREATH_Y * ratioY),
                            (int) (Constants.WestPage.BREATH_WIDTH * ratioX),
                            (int) (Constants.WestPage.BREATH_HEIGHT * ratioY));
                    Bitmap press = Bitmap.createBitmap(bitmap,
                            (int) (Constants.WestPage.PRESS_X * ratioX),
                            (int) (Constants.WestPage.PRESS_Y * ratioY),
                            (int) (Constants.WestPage.PRESS_WIDTH * ratioX),
                            (int) (Constants.WestPage.PRESS_HEIGHT * ratioY));
                    Bitmap pulse = Bitmap.createBitmap(bitmap,
                            (int) (Constants.WestPage.PULSE_X * ratioX),
                            (int) (Constants.WestPage.PULSE_Y * ratioY),
                            (int) (Constants.WestPage.PULSE_WIDTH * ratioX),
                            (int) (Constants.WestPage.PULSE_HEIGHT * ratioY));
                    Bitmap allergy = Bitmap.createBitmap(bitmap,
                            (int) (Constants.WestPage.ALLERGY_X * ratioX),
                            (int) (Constants.WestPage.ALLERGY_Y * ratioY),
                            (int) (Constants.WestPage.ALLERGY_WIDTH * ratioX),
                            (int) (Constants.WestPage.ALLERGY_HEIGHT * ratioY));
                    Bitmap main = Bitmap.createBitmap(bitmap,
                            (int) (Constants.WestPage.MAIN_X * ratioX),
                            (int) (Constants.WestPage.MAIN_Y * ratioY),
                            (int) (Constants.WestPage.MAIN_WIDTH * ratioX),
                            (int) (Constants.WestPage.MAIN_HEIGHT * ratioY));
                    Bitmap now = Bitmap.createBitmap(bitmap,
                            (int) (Constants.WestPage.NOW_X * ratioX),
                            (int) (Constants.WestPage.NOW_Y * ratioY),
                            (int) (Constants.WestPage.NOW_WIDTH * ratioX),
                            (int) (Constants.WestPage.NOW_HEIGHT * ratioY));
                    Bitmap before = Bitmap.createBitmap(bitmap,
                            (int) (Constants.WestPage.BEFORE_X * ratioX),
                            (int) (Constants.WestPage.BEFORE_Y * ratioY),
                            (int) (Constants.WestPage.BEFORE_WIDTH * ratioX),
                            (int) (Constants.WestPage.BEFORE_HEIGHT * ratioY));
                    Bitmap check = Bitmap.createBitmap(bitmap,
                            (int) (Constants.WestPage.CHECK_X * ratioX),
                            (int) (Constants.WestPage.CHECK_Y * ratioY),
                            (int) (Constants.WestPage.CHECK_WIDTH * ratioX),
                            (int) (Constants.WestPage.CHECK_HEIGHT * ratioY));
                    Bitmap first = Bitmap.createBitmap(bitmap,
                            (int) (Constants.WestPage.FIRST_X * ratioX),
                            (int) (Constants.WestPage.FIRST_Y * ratioY),
                            (int) (Constants.WestPage.FIRST_WIDTH * ratioX),
                            (int) (Constants.WestPage.FIRST_HEIGHT * ratioY));
                    Bitmap deal = Bitmap.createBitmap(bitmap,
                            (int) (Constants.WestPage.DEAL_X * ratioX),
                            (int) (Constants.WestPage.DEAL_Y * ratioY),
                            (int) (Constants.WestPage.DEAL_WIDTH * ratioX),
                            (int) (Constants.WestPage.CHECK_HEIGHT * ratioY));
                    bitmapMap.put("tem", tem);
                    bitmapMap.put("breath", breath);
                    bitmapMap.put("pulse", pulse);
                    bitmapMap.put("press", press);
                    bitmapMap.put("main", main);
                    bitmapMap.put("allergy", allergy);
                    bitmapMap.put("now", now);
                    bitmapMap.put("before", before);
                    bitmapMap.put("check", check);
                    bitmapMap.put("first", first);
                    bitmapMap.put("deal", deal);

                }
                break;
                //中医病历
                case 1: {
                    Bitmap allergy = Bitmap.createBitmap(bitmap,
                            (int) (Constants.EastPage.ALLERGY_X * ratioX),
                            (int) (Constants.EastPage.ALLERGY_X * ratioY),
                            (int) (Constants.EastPage.ALLERGY_WIDTH * ratioX),
                            (int) (Constants.EastPage.ALLERGY_HEIGHT * ratioY));

                    Bitmap main = Bitmap.createBitmap(bitmap,
                            (int) (Constants.EastPage.MAIN_X * ratioX),
                            (int) (Constants.EastPage.MAIN_Y * ratioY),
                            (int) (Constants.EastPage.MAIN_WIDTH * ratioX),
                            (int) (Constants.EastPage.MAIN_HEIGHT * ratioY));

                    Bitmap now = Bitmap.createBitmap(bitmap,
                            (int) (Constants.EastPage.NOW_X * ratioX),
                            (int) (Constants.EastPage.NOW_Y * ratioY),
                            (int) (Constants.EastPage.NOW_WIDTH * ratioX),
                            (int) (Constants.EastPage.NOW_HEIGHT * ratioY));

                    //既往史
                    Bitmap before = Bitmap.createBitmap(bitmap,
                            (int) (Constants.EastPage.BEFORE_X * ratioX),
                            (int) (Constants.EastPage.BEFORE_Y * ratioY),
                            (int) (Constants.EastPage.BEFORE_WIDTH * ratioX),
                            (int) (Constants.EastPage.BEFORE_HEIGHT * ratioY));
                    //个人史
                    Bitmap person = Bitmap.createBitmap(bitmap,
                            (int) (Constants.EastPage.PERSON_X * ratioX),
                            (int) (Constants.EastPage.PERSON_Y * ratioY),
                            (int) (Constants.EastPage.PERSON_WIDTH * ratioX),
                            (int) (Constants.EastPage.PERSON_HEIGHT * ratioY));

                    //婚育史
                    Bitmap marry = Bitmap.createBitmap(bitmap,
                            (int) (Constants.EastPage.MARRY_X * ratioX),
                            (int) (Constants.EastPage.MARRY_Y * ratioY),
                            (int) (Constants.EastPage.MARRY_WIDTH * ratioX),
                            (int) (Constants.EastPage.MARRY_HEIGHT * ratioY));

                    //家族史
                    Bitmap family = Bitmap.createBitmap(bitmap,
                            (int) (Constants.EastPage.FAMILY_X * ratioX),
                            (int) (Constants.EastPage.FAMILY_Y * ratioY),
                            (int) (Constants.EastPage.FAMILY_WIDTH * ratioX),
                            (int) (Constants.EastPage.FAMILY_HEIGHT * ratioY));
                    //望
                    Bitmap look = Bitmap.createBitmap(bitmap,
                            (int) (Constants.EastPage.LOOK_X * ratioX),
                            (int) (Constants.EastPage.LOOK_Y * ratioY),
                            (int) (Constants.EastPage.LOOK_WIDTH * ratioX),
                            (int) (Constants.EastPage.LOOK_HEIGHT * ratioY));
                    //闻
                    Bitmap smell = Bitmap.createBitmap(bitmap,
                            (int) (Constants.EastPage.SMELL_X * ratioX),
                            (int) (Constants.EastPage.SMELL_Y * ratioY),
                            (int) (Constants.EastPage.SMELL_WIDTH * ratioX),
                            (int) (Constants.EastPage.SMELL_HEIGHT * ratioY));

                    //切脉
                    Bitmap pulse = Bitmap.createBitmap(bitmap,
                            (int) (Constants.EastPage.PULSE_X * ratioX),
                            (int) (Constants.EastPage.PULSE_Y * ratioY),
                            (int) (Constants.EastPage.PULSE_WIDTH * ratioX),
                            (int) (Constants.EastPage.PULSE_HEIGHT * ratioY));

                    //查体
                    Bitmap body = Bitmap.createBitmap(bitmap,
                            (int) (Constants.EastPage.BODY_X * ratioX),
                            (int) (Constants.EastPage.BODY_Y * ratioY),
                            (int) (Constants.EastPage.BODY_WIDTH * ratioX),
                            (int) (Constants.EastPage.BODY_HEIGHT * ratioY));

                    Bitmap check = Bitmap.createBitmap(bitmap,
                            (int) (Constants.EastPage.CHECK_X * ratioX),
                            (int) (Constants.EastPage.CHECK_Y * ratioY),
                            (int) (Constants.EastPage.CHECK_WIDTH * ratioX),
                            (int) (Constants.EastPage.CHECK_HEIGHT * ratioY));
                    Bitmap first = Bitmap.createBitmap(bitmap,
                            (int) (Constants.EastPage.FIRST_X * ratioX),
                            (int) (Constants.EastPage.FIRST_Y * ratioY),
                            (int) (Constants.EastPage.FIRST_WIDTH * ratioX),
                            (int) (Constants.EastPage.FIRST_HEIGHT * ratioY));
                    Bitmap drugs = Bitmap.createBitmap(bitmap,
                            (int) (Constants.EastPage.DRUG_X * ratioX),
                            (int) (Constants.EastPage.DRUG_Y * ratioY),
                            (int) (Constants.EastPage.DRUG_WIDTH * ratioX),
                            (int) (Constants.EastPage.DRUG_HEIGHT * ratioY));
                    Bitmap deal = Bitmap.createBitmap(bitmap,
                            (int) (Constants.EastPage.DEAL_X * ratioX),
                            (int) (Constants.EastPage.DEAL_Y * ratioY),
                            (int) (Constants.EastPage.DEAL_WIDTH * ratioX),
                            (int) (Constants.EastPage.CHECK_HEIGHT * ratioY));
                    bitmapMap.put("allergy", allergy);
                    bitmapMap.put("main", main);
                    bitmapMap.put("now", now);
                    bitmapMap.put("before", before);
                    bitmapMap.put("person", person);
                    bitmapMap.put("marry", marry);
                    bitmapMap.put("family", family);
                    bitmapMap.put("look", look);
                    bitmapMap.put("smell", smell);
                    bitmapMap.put("pulse", pulse);
                    bitmapMap.put("body", body);
                    bitmapMap.put("check", check);
                    bitmapMap.put("first", first);
                    bitmapMap.put("drugs", drugs);
                    bitmapMap.put("deal", deal);
                }
                break;
                default:
                    break;
            }

            Bundle bundle = new Bundle();
            bundle.putParcelable("image", bitmap);
            bundle.putSerializable("images", bitmapMap);
            bundle.putInt("blId", blId);
            bundle.putInt("ghId", ghId);
            bundle.putInt("hzId", hzId);

            if (blModel == 0) {
                //西医表单
                bundle.putParcelableArrayList("pictures", mData);
                FormActivity.startAction(getContext(), bundle);
            } else {
                bundle.putParcelableArrayList("faceImg", mFaceData);
                bundle.putParcelableArrayList("tongueImg", mTongueData);
                ChineseFormActivity.startAction(getContext(), bundle);
            }
        }, 2000);
    }

    private void clickAiHelp() {
        PopTip.tip("测试功能：识别医生手写主诉后，识别内容辅助看诊......");
        FullScreenDialog.show(new OnBindView<FullScreenDialog>(R.layout.dialog_chat) {
            @SuppressLint("NotifyDataSetChanged")
            @Override
            public void onBind(FullScreenDialog customDialog, View view) {
                try {
                    getWriteToken(view);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                RecyclerView recyclerView = view.findViewById(R.id.rvChat);
                ImageView ivPlaceholder = view.findViewById(R.id.ivPlaceholder);
                LoadingView tvPlaceholderMsgLeft = view.findViewById(R.id.tvPlaceholderMsgLeft);
                LinearLayout llPlaceholder = view.findViewById(R.id.llPlaceholder);

                recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
                adapter = new MsgAdapter(messagesDTOList);
                recyclerView.setAdapter(adapter);

                view.findViewById(R.id.tvTips).setOnClickListener(v -> {

                    messagesDTOList.add(new ChatBodyBean.MessagesDTO("user", words.toString()));//用户的问题
                    adapter.notifyDataSetChanged();
                    adapter.notifyItemInserted(messagesDTOList.size() - 1);
                    recyclerView.scrollToPosition(messagesDTOList.size() - 1);


                    //显示占位符加载动画
                    ivPlaceholder.setVisibility(View.VISIBLE);
                    llPlaceholder.setVisibility(View.VISIBLE);
                    tvPlaceholderMsgLeft.animation();
                    getChatToken(view);//请求token

                });
            }
        });
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    String getFileContentAsBase64(Bitmap bitmap) throws IOException {
//        Bitmap bitmap= BitmapFactory.decodeResource(this.getResources(),R.drawable.write);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        byte[] b = baos.toByteArray();
        String base64 = Base64.getEncoder().encodeToString(b);
        base64 = URLEncoder.encode(base64, "utf-8");
        return base64;
    }

    @SuppressLint("CheckResult")
    public void getWriteToken(View view) throws InterruptedException {

        bitmap = screenshot(mCurDrawView);
        Thread.sleep(500);

        float ratioX = ((float) mCurDrawView.getWidth() / (float) Constants.A4_WIDTH);
        float ratioY = ((float) mCurDrawView.getHeight() / (float) Constants.A4_HEIGHT);
        Bitmap main;
        if (blModel == 0) {
            main = Bitmap.createBitmap(bitmap,
                    (int) (Constants.WestPage.MAIN_X * ratioX),
                    (int) (Constants.WestPage.MAIN_Y * ratioY),
                    (int) (Constants.WestPage.MAIN_WIDTH * ratioX),
                    (int) (Constants.WestPage.MAIN_HEIGHT * ratioY));
        } else {
            main = Bitmap.createBitmap(bitmap,
                    (int) (Constants.EastPage.MAIN_X * ratioX),
                    (int) (Constants.EastPage.MAIN_Y * ratioY),
                    (int) (Constants.EastPage.MAIN_WIDTH * ratioX),
                    (int) (Constants.EastPage.MAIN_HEIGHT * ratioY));
        }

        ChatRetrofitUtils.getInstance().create(Apis.class).getBaiduToken(
                GlobalConfig.write_client_key, GlobalConfig.write_secret_key,
                "client_credentials")
                .compose(new SchedulerTransformer<>())
                .subscribe(bean -> {
                    if (bean != null) {
                        String accessToken = bean.accessToken;
                        startWrite(accessToken, getFileContentAsBase64(main), view);
                    } else {
                        ToastUtils.showShort("body为空");
                    }
                });
    }

    @SuppressWarnings("all")
    private void startWrite(String accessToken, String image, View view) {
        // image 可以通过 getFileContentAsBase64("C:\fakepath\Android Gradle.png") 方法获取,如果Content-Type是application/x-www-form-urlencoded时,第二个参数传true
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body = RequestBody.create(mediaType, "image=" + image +
                "&detect_direction=false&probability=false");
        ChatRetrofitUtils.getInstance().create(Apis.class).getWriteResult(body, accessToken)
                .compose(new SchedulerTransformer<>())
                .subscribe(bean -> {
                    if (bean.wordsResult == null || bean.wordsResult.size() <= 0) {
                        runOnUiThread(() -> PopTipUtils.errMsg("未识别到字体"));
                    } else {
                        words = new StringBuilder();
                        words.append("患者出现");
                        for (int i = 0; i < bean.wordsResult.size(); ++i) {
                            words.append(bean.wordsResult.get(i).words);
                        }
                        words.append("等症状，怎么处理?");
                        TextView tvTips = view.findViewById(R.id.tvTips);
                        tvTips.setText(words);
                    }
                });

    }

    /**
     * 获取bitmap
     */
    @SuppressWarnings("unused")
    private Bitmap getBitmap(SurfaceView view) {
        WindowManager manager = getWindowManager();
        DisplayMetrics metrics = new DisplayMetrics();
        manager.getDefaultDisplay().getMetrics(metrics);
        int width = metrics.widthPixels;
        int height = metrics.heightPixels;
        int measureWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);
        int measureHeight = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.AT_MOST);
        view.measure(measureWidth, measureHeight);
        view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
        Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
        final Canvas canvas = new Canvas(bitmap);
        view.draw(canvas);
        return bitmap;

    }


    public Bitmap screenshot(SurfaceView view) {
        //获取到SurfaceView上的内容
        Bitmap mScreenBitmap;
        //需要截取的长和宽
        int outWidth = view.getWidth();
        int outHeight = view.getHeight();
        LogUtils.i("width=" + outWidth + "\n" +
                "height=" + outHeight);

        CanvasDrawView myView = (CanvasDrawView) view;
        mScreenBitmap = Bitmap.createBitmap(outWidth, outHeight, Bitmap.Config.ARGB_8888);
        PixelCopy.request(myView, mScreenBitmap, copyResult -> {
            if (PixelCopy.SUCCESS == copyResult) {
                Log.i("lixu", "SUCCESS ");
            } else {
                Log.i("lixu", "FAILED");
            }
        }, new Handler());
        return mScreenBitmap;//位图
    }


    /**
     * 获取 Token
     */
    @SuppressLint("CheckResult")
    public void getChatToken(View view) {
        ChatRetrofitUtils.getInstance().create(Apis.class).getBaiduToken(
                GlobalConfig.client_KEY, GlobalConfig.SECRET_KEY,
                "client_credentials")
                .compose(new SchedulerTransformer<>())
                .subscribe(bean -> {
                    if (bean != null) {
                        String accessToken = bean.accessToken;
                        startChat(accessToken, view);
                    } else {
                        ToastUtils.showShort("body为空");
                    }
                });
    }

    /**
     * 开始 chat
     */
    @SuppressLint("CheckResult")
    public void startChat(String accessToken, View view) {

        RecyclerView recyclerView = view.findViewById(R.id.rvChat);
        ImageView ivPlaceholder = view.findViewById(R.id.ivPlaceholder);
        LoadingView tvPlaceholderMsgLeft = view.findViewById(R.id.tvPlaceholderMsgLeft);
        LinearLayout llPlaceholder = view.findViewById(R.id.llPlaceholder);

        //构造对话实体类，后面需要改为根据用户输入动态添加
        ChatBodyBean chatBodyBean = new ChatBodyBean();
        chatBodyBean.messages = messagesDTOList;
        //将参数实体转换为RequestBody
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, JSONObject.toJSONString(chatBodyBean));
        ChatRetrofitUtils.getInstance().create(Apis.class).startChat(body, accessToken)
                .compose(new SchedulerTransformer<>())
                .subscribe(bean -> {
                    String result = bean.result;
                    messagesDTOList.add(new ChatBodyBean.MessagesDTO("assistant", ""));//将回答添加到实体中，为下次提问做准备

                    runOnUiThread(() -> {
                        //移除占位view
                        llPlaceholder.setVisibility(View.GONE);
                        ivPlaceholder.setVisibility(View.GONE);
                        tvPlaceholderMsgLeft.stopAnimation();

                    });


                    int length = result.length();
                    final int[] index = {0};
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            while (index[0] < length) {
                                try {
                                    Thread.sleep(20);
                                    runOnUiThread(new Runnable() {
                                        @Override
                                        public void run() {
                                            messagesDTOList.get(messagesDTOList.size() - 1).content = result.substring(0, index[0]);
                                            //刷新列表
                                            adapter.notifyDataSetChanged();
                                            adapter.notifyItemInserted(messagesDTOList.size() - 1);
                                            recyclerView.scrollToPosition(messagesDTOList.size() - 1);
                                        }
                                    });
                                    index[0]++;
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }).start();
                });

    }

    //调用相机拍照
    private void takePicture() {
        PictureSelector.create(this)
                .openCamera(SelectMimeType.ofImage())
                .setCompressEngine(new ImageFileCompressEngine())//设置压缩图片引擎
                .forResultActivity(PictureConfig.REQUEST_CAMERA);
    }

    /**
     * 自定义压缩
     */
    private static class ImageFileCompressEngine implements CompressFileEngine {
        @Override
        public void onStartCompress(Context context, ArrayList<Uri> source, OnKeyValueResultCallbackListener call) {
            Luban.with(context).load(source).ignoreBy(100).setRenameListener(new OnRenameListener() {
                @Override
                public String rename(String filePath) {
                    int indexOf = filePath.lastIndexOf(".");
                    String postfix = indexOf != -1 ? filePath.substring(indexOf) : ".jpg";
                    return DateUtils.getCreateFileName("CMP_") + postfix;
                }
            }).filter(path -> {
                if (PictureMimeType.isUrlHasImage(path) && !PictureMimeType.isHasHttp(path)) {
                    return true;
                }
                return !PictureMimeType.isUrlHasGif(path);
            }).setCompressListener(new OnNewCompressListener() {
                @Override
                public void onStart() {

                }

                @Override
                public void onSuccess(String source, File compressFile) {
                    if (call != null) {
                        call.onCallback(source, compressFile.getAbsolutePath());
                    }
                }

                @Override
                public void onError(String source, Throwable e) {
                    if (call != null) {
                        call.onCallback(source, null);
                    }
                }
            }).launch();
        }
    }

    //回调，获取用户选择的图片
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                case PictureConfig.CHOOSE_REQUEST:
                case PictureConfig.REQUEST_CAMERA: {
                    //保存选中的照片
                    if (blModel == 0) {
                        mData.addAll(PictureSelector.obtainSelectorList(data));
                        mBinding.tvPicNum.setVisibility(View.VISIBLE);
                        mBinding.tvPicNum.setText("" + mData.size());
                    } else {
                        if (typeImg == 0) {
                            mFaceData.addAll(PictureSelector.obtainSelectorList(data));
                            mBinding.tvPicNum.setVisibility(View.VISIBLE);
                            mBinding.tvPicNum.setText("" + mFaceData.size());
                        } else {
                            mTongueData.addAll(PictureSelector.obtainSelectorList(data));
                            mBinding.tvTonguePicNum.setVisibility(View.VISIBLE);
                            mBinding.tvTonguePicNum.setText("" + mTongueData.size());
                        }
                    }

                }
                break;
            }
        } else if (resultCode == RESULT_CANCELED) {
            PopTip.tip("选择图片回调失败");
        }
    }
}
